package com.victor.register;

import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Created by DJJ on 2019/3/12.
 */
//用于地址发现,用于实时获取最新的rpc服务信息
    //地址发现一般用于客户端远程调用服务端时的使用
public class RpcDiscover {
    public static final Logger LOGGER= LoggerFactory.getLogger(RpcRegistry.class);
    //服务端地址 zkServer的地址
    private String registryAddress;
    //获取所有提供服务的服务器列表
    private volatile List<String> dataList=new ArrayList<>();

    public String getRegistryAddress() {
        return registryAddress;
    }

    public void setRegistryAddress(String registryAddress) {
        this.registryAddress = registryAddress;
    }

    public List<String> getDataList() {
        return dataList;
    }

    public void setDataList(List<String> dataList) {
        this.dataList = dataList;
    }
    private ZooKeeper zooKeeper;
    //初始化
    public RpcDiscover(String registryAddress) throws Exception {
        this.registryAddress = registryAddress;
        zooKeeper= new ZooKeeper(registryAddress, Constant.SESSION_TIMEOUT, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                if (watchedEvent.getType()==Event.EventType.NodeChildrenChanged){
                    //监听zkservice的变化,有变化才执行这里
                    watchNode();
                }
            }
        });
        //没变化直接从这里获取
        watchNode();
    }
    // 从dataList列表随机获取一个可用的服务端的地址信息给rpc-client
    public String discover(){
        int size=dataList.size();
        if(size>0){
            int index= new Random().nextInt(size);
            return dataList.get(index);
        }
        throw new RuntimeException("没有找到对应的服务器");
    }
    //监听服务端的列表信息
    private void watchNode(){
        try {
            List<String> children = zooKeeper.getChildren(Constant.REGISTRY_PATH, true);
            List<String> datalist=new ArrayList<>();
            for (String node : children) {
                byte[] data = zooKeeper.getData(Constant.REGISTRY_PATH + "/" + node, false, null);
                datalist.add(new String(data));
            }
            this.dataList=datalist;
        } catch (Exception e) {
            LOGGER.error("监听服务端的列表信息出错",e);
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        RpcDiscover rpcDiscover=new RpcDiscover("127.0.0.1:2181");
        System.out.println(rpcDiscover.discover());
    }
}
